﻿using System;
using System.Collections.Generic;

namespace Library.Reflection
{
    public static class Extensions
    {
        public static IEnumerable<Type[]> GetGenericArguments(this Type type, Type genericTypeDefinition)
        {
            if (type == null) throw new ArgumentNullException("type");
            if (genericTypeDefinition == null) throw new ArgumentNullException("genericTypeDefinition");
            if (!genericTypeDefinition.IsGenericTypeDefinition) throw new ArgumentException(string.Empty, "genericTypeDefinition");

            if (type.IsGenericType && type.GetGenericTypeDefinition() == genericTypeDefinition)
            {
                yield return type.GetGenericArguments();
                yield break;
            }

            if (genericTypeDefinition.IsInterface)
            {
                Type[] interfaces = type.GetInterfaces();
                int n = interfaces.Length;
                for (int i = 0; i < n; ++i)
                {
                    Type item = interfaces[i];
                    if (item.IsGenericType && item.GetGenericTypeDefinition() == genericTypeDefinition)
                    {
                        yield return item.GetGenericArguments();
                    }
                }
                yield break;
            }
            else
            {
                if (type.IsClass)
                {
                    type = type.BaseType;

                    while (type != null)
                    {
                        if (type.IsGenericType && type.GetGenericTypeDefinition() == genericTypeDefinition)
                        {
                            yield return type.GetGenericArguments();
                            yield break;
                        }
                        else
                        {
                            type = type.BaseType;
                        }
                    }
                }
                yield break;
            }
        }
    }
}
